package com.wgo.bpot.server.integrationtest.performance;

import java.util.concurrent.atomic.AtomicLong;

import junit.framework.Assert;
import remato.common.domain.helpers.Nameable;
import remato.domain.common.Category;
import remato.domain.common.Project;
import remato.domain.common.Requirement;
import remato.domain.common.RequirementSystem;

import com.wgo.precise.client.common.session.PreciseSession;

public class PerformanceHelper {
    private PreciseSession session;
    private AtomicLong uniqueNameIterator = new AtomicLong(0l);

    public PerformanceHelper(PreciseSession session) {
        super();
        this.session = session;
    }

    public void setSession(PreciseSession session) {
        this.session = session;
    }

    public long createConcepts(int noProjects, int noCategories, int noRequirements) {
        long total = 0;
        RequirementSystem reqSys = session.getRootSystem(RequirementSystem.class);
        for (int p= 0; p < noProjects; p++) {
            Project proj = createProject();
            reqSys.addProjectChild(proj);
            ++total;
            for (int c= 0; c < noCategories; c++) {
                Category cat = createCategory();
                proj.addCategoryChild(cat);
                ++total;
                for (int r= 0; r < noRequirements; r++) {
                    Requirement req = createRequirement();
                    cat.addRequirement(req);
                    ++total;
                }
            }
        }
        return total;
    }
    
    public long addProjects(int noProjects) {
        long total = 0;
        RequirementSystem reqSys = session.getRootSystem(RequirementSystem.class);
        for (int p= 0; p < noProjects; p++) {
            reqSys.addProjectChild(createProject());
            ++total;
        }
        Assert.assertTrue(noProjects == 0 || 0 < total);
        return total;
    }    
    
    public long addCategories(int noCategories) {
        long total = 0;
        RequirementSystem reqSys = session.getRootSystem(RequirementSystem.class);
        for (Project project : reqSys.getProjectChildren()) {
            for (int c= 0; c < noCategories; c++) {
                project.addCategoryChild(createCategory());
                ++total;
            }
        }
        Assert.assertTrue(noCategories == 0 || 0 < total);
        return total;
    }    
    
    public long addRequirements(int noRequirements) {
        long total = 0;
        RequirementSystem reqSys = session.getRootSystem(RequirementSystem.class);
        for (Project project : reqSys.getProjectChildren()) {
            for (Category category : project.getCategoryChildren()) {
                for (int r= 0; r < noRequirements; r++) {
                    category.addRequirement(createRequirement());
                    ++total;
                }
            }
        }
        Assert.assertTrue(noRequirements == 0 || 0 < total);
        return total;
    }    
    
    
    public Project createProject(){
        return createConcept(Project.class);
    }
    
    public Requirement createRequirement(){
        return createConcept(Requirement.class);
    }
    
    public Category createCategory(){
        return createConcept(Category.class);
    }
    
    public <T extends Nameable> T createConcept(Class<T> c,String name){
        T t = session.createConcept(c);
        t.setName(name);
        return t;
    }
    
    public <T extends Nameable> T createConcept(Class<T> c){
        T t = session.createConcept(c);
        t.setName(getUniqueName());
        return t;
    }
    
    private String getUniqueName(){
        return ""+uniqueNameIterator.incrementAndGet();
    }
}
